Various fixes and enhancements (#565)

This PR does a number of fixes and enhancements:
- [Added FileFsAttributeInformation fs info
class](c0fd8ebf51)
- [Added FileIsRemoteDeviceInformation file info
class](c8a18cf61c)
- [Added FileIdInformation file info
class](2c82277b5e)
- [Implemented NtUserEnumDisplaySettings
syscall](54ebbe27c2)
- [Fixed the DISPLAY_DEVICEW
value](4fbd65a302),
the old one had `StateFlags` set to 0 but that's incorrect since at
least one display needs to be the primary display.
- [Added support for SHA256 in
KSecDD](0d06e6822a)
- [Initialized StaticUnicodeString in
TEB](1c89c4e3b3),
this was necessary to get `RtlAnsiStringToUnicodeString` working.
- [Added '\??\pipe\' prefix to
is_named_pipe_path](d20da12052)
- [Stubbed
NtSetSecurityObject](c07f541528)
- [Don't request 'file_size' for
directories](46b97fd91c),
because this causes an exception in Linux.
- [Optimized
module_manager::get_module](83aa3b663a),
this seems to increase the emulator's speed by around 10%.
This commit is contained in:
Maurice Heumann
2025-10-25 10:54:01 +02:00
committed by GitHub
12 changed files with 281 additions and 43 deletions

View File

@@ -309,6 +309,14 @@ typedef struct _FILE_FS_DEVICE_INFORMATION
ULONG Characteristics;
} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
typedef struct _FILE_FS_ATTRIBUTE_INFORMATION
{
ULONG FileSystemAttributes;
LONG MaximumComponentNameLength;
ULONG FileSystemNameLength;
char16_t FileSystemName[10];
} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
typedef struct _FILE_POSITION_INFORMATION
{
LARGE_INTEGER CurrentByteOffset;
@@ -320,6 +328,24 @@ typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION
ULONG ReparseTag;
} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION;
typedef struct _FILE_IS_REMOTE_DEVICE_INFORMATION
{
BOOLEAN IsRemote;
} FILE_IS_REMOTE_DEVICE_INFORMATION, *PFILE_IS_REMOTE_DEVICE_INFORMATION;
#ifndef OS_WINDOWS
typedef struct _FILE_ID_128
{
BYTE Identifier[16];
} FILE_ID_128, *PFILE_ID_128;
#endif
typedef struct _FILE_ID_INFORMATION
{
ULONGLONG VolumeSerialNumber;
FILE_ID_128 FileId;
} FILE_ID_INFORMATION, *PFILE_ID_INFORMATION;
typedef struct _FILE_STANDARD_INFORMATION
{
LARGE_INTEGER AllocationSize;
@@ -413,11 +439,6 @@ typedef struct _FILE_RENAME_INFORMATION
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
#ifndef OS_WINDOWS
typedef struct _FILE_ID_128
{
BYTE Identifier[16];
} FILE_ID_128, *PFILE_ID_128;
typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE;
typedef struct _SECURITY_QUALITY_OF_SERVICE
{

View File

@@ -52,4 +52,63 @@ struct EMU_DISPLAY_DEVICEW
char16_t DeviceKey[128];
};
#ifndef ENUM_CURRENT_SETTINGS
#define ENUM_CURRENT_SETTINGS ((DWORD) - 1)
#endif
struct EMU_DEVMODEW
{
char16_t dmDeviceName[32];
WORD dmSpecVersion;
WORD dmDriverVersion;
WORD dmSize;
WORD dmDriverExtra;
DWORD dmFields;
union
{
struct
{
int16_t dmOrientation;
int16_t dmPaperSize;
int16_t dmPaperLength;
int16_t dmPaperWidth;
int16_t dmScale;
int16_t dmCopies;
int16_t dmDefaultSource;
int16_t dmPrintQuality;
} s;
POINT dmPosition;
struct
{
POINT dmPosition;
DWORD dmDisplayOrientation;
DWORD dmDisplayFixedOutput;
} s2;
} u;
int16_t dmColor;
int16_t dmDuplex;
int16_t dmYResolution;
int16_t dmTTOption;
int16_t dmCollate;
char16_t dmFormName[32];
WORD dmLogPixels;
DWORD dmBitsPerPel;
DWORD dmPelsWidth;
DWORD dmPelsHeight;
union
{
DWORD dmDisplayFlags;
DWORD dmNup;
} u2;
DWORD dmDisplayFrequency;
DWORD dmICMMethod;
DWORD dmICMIntent;
DWORD dmMediaType;
DWORD dmDitherType;
DWORD dmReserved1;
DWORD dmReserved2;
DWORD dmPanningWidth;
DWORD dmPanningHeight;
};
// NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)

View File

@@ -19,26 +19,18 @@ namespace utils::string
template <typename T, size_t Size>
requires(std::is_trivially_copyable_v<T>)
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
void copy(T (&array)[Size], const std::basic_string_view<T> str)
void copy(T (&array)[Size], const T* str)
{
if constexpr (Size == 0)
{
return;
}
const auto size = std::min(Size, str.size());
memcpy(array, str.data(), size * sizeof(T));
const auto size = std::min(Size, std::char_traits<T>::length(str));
memcpy(array, str, size * sizeof(T));
array[std::min(Size - 1, size)] = {};
}
template <typename T, size_t Size>
requires(std::is_trivially_copyable_v<T>)
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
void copy(T (&array)[Size], const T* str)
{
copy<T, Size>(array, std::basic_string_view<T>(str));
}
inline char char_to_lower(const char val)
{
return static_cast<char>(std::tolower(static_cast<unsigned char>(val)));

View File

@@ -9,7 +9,7 @@ namespace
{
// RNG Microsoft Primitive Provider
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
std::uint8_t output_data[216] = //
std::uint8_t rng_output_data[216] = //
{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
@@ -22,6 +22,21 @@ namespace
0x70, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x73, 0x00,
0x2E, 0x00, 0x64, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// SHA256 Microsoft Primitive Provider
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
std::uint8_t sha256_output_data[224] = //
{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x32, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x53, 0x00, 0x48, 0x00,
0x41, 0x00, 0x32, 0x00, 0x35, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, 0x6F,
0x00, 0x73, 0x00, 0x6F, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00,
0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x76, 0x00, 0x69, 0x00, 0x64,
0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, 0x74, 0x00, 0x70,
0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2E, 0x00,
0x64, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
NTSTATUS io_control(windows_emulator& win_emu, const io_device_context& c) override
{
if (c.io_control_code != 0x390400)
@@ -33,13 +48,32 @@ namespace
if (operation == 2)
{
win_emu.emu().write_memory(c.output_buffer, output_data);
std::array<char16_t, 8> alg_name_buffer{};
win_emu.emu().read_memory(c.input_buffer + 0x30, alg_name_buffer.data(), sizeof(alg_name_buffer));
if (c.io_status_block)
const std::u16string algorithm_name(alg_name_buffer.data());
if (algorithm_name == u"SHA256")
{
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
block.Information = sizeof(output_data);
c.io_status_block.write(block);
win_emu.emu().write_memory(c.output_buffer, sha256_output_data);
if (c.io_status_block)
{
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
block.Information = sizeof(sha256_output_data);
c.io_status_block.write(block);
}
}
else
{
win_emu.emu().write_memory(c.output_buffer, rng_output_data);
if (c.io_status_block)
{
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
block.Information = sizeof(rng_output_data);
c.io_status_block.write(block);
}
}
}

View File

@@ -119,6 +119,8 @@ emulator_thread::emulator_thread(memory_manager& memory, const process_context&
teb_obj.NtTib.Self = this->teb->value();
teb_obj.CurrentLocale = 0x409;
teb_obj.ProcessEnvironmentBlock = context.peb.value();
teb_obj.StaticUnicodeString.MaximumLength = sizeof(teb_obj.StaticUnicodeBuffer);
teb_obj.StaticUnicodeString.Buffer = this->teb->value() + offsetof(TEB64, StaticUnicodeBuffer);
});
}

View File

@@ -46,7 +46,7 @@ struct mapped_module
bool contains(const uint64_t address) const
{
return address >= this->image_base && address < (this->image_base + this->size_of_image);
return (address - this->image_base) < this->size_of_image;
}
uint64_t find_export(const std::string_view export_name) const

View File

@@ -156,6 +156,7 @@ mapped_module* module_manager::map_memory_module(uint64_t base_address, uint64_t
const auto image_base = mod.image_base;
const auto entry = this->modules_.try_emplace(image_base, std::move(mod));
this->last_module_cache_ = this->modules_.end();
this->callbacks_->on_module_load(entry.first->second);
return &entry.first->second;
}
@@ -183,6 +184,7 @@ void module_manager::serialize(utils::buffer_serializer& buffer) const
void module_manager::deserialize(utils::buffer_deserializer& buffer)
{
buffer.read_map(this->modules_);
this->last_module_cache_ = this->modules_.end();
const auto executable_base = buffer.read<uint64_t>();
const auto ntdll_base = buffer.read<uint64_t>();
@@ -209,6 +211,7 @@ bool module_manager::unmap(const uint64_t address)
this->callbacks_->on_module_unload(mod->second);
unmap_module(*this->memory_, mod->second);
this->modules_.erase(mod);
this->last_module_cache_ = this->modules_.end();
return true;
}

View File

@@ -83,9 +83,15 @@ class module_manager
callbacks* callbacks_{};
module_map modules_{};
mutable module_map::iterator last_module_cache_{modules_.end()};
module_map::iterator get_module(const uint64_t address)
{
if (last_module_cache_ != this->modules_.end() && last_module_cache_->second.contains(address))
{
return last_module_cache_;
}
if (this->modules_.empty())
{
return this->modules_.end();
@@ -101,6 +107,7 @@ class module_manager
if (upper_bound->second.contains(address))
{
last_module_cache_ = upper_bound;
return upper_bound;
}

View File

@@ -31,7 +31,7 @@ inline bool is_syscall(const std::string_view name)
inline bool is_named_pipe_path(const std::u16string_view& filename)
{
return filename == u"\\Device\\NamedPipe\\" || filename.starts_with(u"\\Device\\NamedPipe\\");
return filename == u"\\Device\\NamedPipe\\" || filename.starts_with(u"\\Device\\NamedPipe\\") || filename.starts_with(u"\\??\\pipe\\");
}
inline std::optional<uint32_t> extract_syscall_id(const exported_symbol& symbol, std::span<const std::byte> data)

View File

@@ -155,6 +155,7 @@ namespace syscalls
NTSTATUS handle_NtSetInformationObject();
NTSTATUS handle_NtQuerySecurityObject(const syscall_context& c, handle /*h*/, SECURITY_INFORMATION /*security_information*/,
emulator_pointer security_descriptor, ULONG length, emulator_object<ULONG> length_needed);
NTSTATUS handle_NtSetSecurityObject();
// syscalls/port.cpp:
NTSTATUS handle_NtConnectPort(const syscall_context& c, emulator_object<handle> client_port_handle,
@@ -911,32 +912,78 @@ namespace syscalls
return FALSE;
}
NTSTATUS handle_NtUserEnumDisplayDevices(const syscall_context& /*c*/,
NTSTATUS handle_NtUserEnumDisplayDevices(const syscall_context& c,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> str_device, const DWORD dev_num,
const emulator_object<EMU_DISPLAY_DEVICEW> display_device, const DWORD /*flags*/)
{
if (str_device && dev_num != 0)
if (!str_device)
{
return STATUS_UNSUCCESSFUL;
}
if (dev_num > 0)
{
return STATUS_UNSUCCESSFUL;
}
if (dev_num > 0)
display_device.access([&](EMU_DISPLAY_DEVICEW& dev) {
dev.StateFlags = 0x5; // DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1");
utils::string::copy(dev.DeviceString, u"Emulated Virtual Adapter");
utils::string::copy(dev.DeviceID, u"PCI\\VEN_10DE&DEV_0000&SUBSYS_00000000&REV_A1");
utils::string::copy(dev.DeviceKey, u"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\{00000001-"
u"0002-0003-0004-000000000005}\\0000");
});
}
else
{
return STATUS_UNSUCCESSFUL;
}
const auto dev_name = read_unicode_string(c.emu, str_device);
display_device.access([&](EMU_DISPLAY_DEVICEW& dev) {
dev.StateFlags = 0;
utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1");
utils::string::copy(dev.DeviceID, u"PCI\\VEN_10DE&DEV_0000&SUBSYS_00000000&REV_A1");
utils::string::copy(dev.DeviceString, u"Emulator Display");
utils::string::copy(dev.DeviceKey, u"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\{00000001-"
u"0002-0003-0004-000000000005}\\0001");
});
if (dev_name != u"\\\\.\\DISPLAY1")
{
return STATUS_UNSUCCESSFUL;
}
if (dev_num > 0)
{
return STATUS_UNSUCCESSFUL;
}
display_device.access([&](EMU_DISPLAY_DEVICEW& dev) {
dev.StateFlags = 0x1; // DISPLAY_DEVICE_ACTIVE
utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1\\Monitor0");
utils::string::copy(dev.DeviceString, u"Generic PnP Monitor");
utils::string::copy(dev.DeviceID, u"MONITOR\\EMU1234\\{4d36e96e-e325-11ce-bfc1-08002be10318}\\0000");
utils::string::copy(dev.DeviceKey, u"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\DISPLAY\\EMU1234\\"
u"1&23a45b&0&UID67568640");
});
}
return STATUS_SUCCESS;
}
NTSTATUS handle_NtUserEnumDisplaySettings(const syscall_context& c,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> device_name,
const DWORD mode_num, const emulator_object<EMU_DEVMODEW> dev_mode, const DWORD /*flags*/)
{
if (dev_mode && (mode_num == ENUM_CURRENT_SETTINGS || mode_num == 0))
{
const auto dev_name = read_unicode_string(c.emu, device_name);
if (dev_name == u"\\\\.\\DISPLAY1")
{
dev_mode.access([](EMU_DEVMODEW& dm) {
dm.dmFields = 0x5C0000; // DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY
dm.dmPelsWidth = 1920;
dm.dmPelsHeight = 1080;
dm.dmBitsPerPel = 32;
dm.dmDisplayFrequency = 60;
});
return STATUS_SUCCESS;
}
}
return STATUS_UNSUCCESSFUL;
}
NTSTATUS handle_NtAssociateWaitCompletionPacket()
{
return STATUS_SUCCESS;
@@ -1131,6 +1178,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
add_handler(NtUserGetRawInputDeviceList);
add_handler(NtUserGetKeyboardType);
add_handler(NtUserEnumDisplayDevices);
add_handler(NtUserEnumDisplaySettings);
add_handler(NtUserSetProp);
add_handler(NtUserSetProp2);
add_handler(NtUserChangeWindowMessageFilterEx);
@@ -1154,6 +1202,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
add_handler(NtReleaseWorkerFactoryWorker);
add_handler(NtAlpcCreateSecurityContext);
add_handler(NtAlpcDeleteSecurityContext);
add_handler(NtSetSecurityObject);
#undef add_handler
}

View File

@@ -182,8 +182,18 @@ namespace syscalls
return handle_query<FILE_FS_VOLUME_INFORMATION>(c.emu, fs_information, length, io_status_block,
[&](FILE_FS_VOLUME_INFORMATION&) {});
case FileFsAttributeInformation:
return handle_query<_FILE_FS_ATTRIBUTE_INFORMATION>(
c.emu, fs_information, length, io_status_block, [&](_FILE_FS_ATTRIBUTE_INFORMATION& info) {
info.FileSystemAttributes = 0x40006; // FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK | FILE_NAMED_STREAMS
info.MaximumComponentNameLength = 255;
constexpr auto name = u"NTFS"sv;
info.FileSystemNameLength = static_cast<ULONG>(name.size() * sizeof(char16_t));
memcpy(info.FileSystemName, name.data(), info.FileSystemNameLength);
});
default:
c.win_emu.log.error("Unsupported fs info class: %X\n", fs_information_class);
c.win_emu.log.error("Unsupported fs info class: 0x%X\n", fs_information_class);
c.emu.stop();
return write_io_status(io_status_block, STATUS_NOT_SUPPORTED, true);
}
@@ -211,7 +221,7 @@ namespace syscalls
files.emplace_back(file_entry{
.file_path = file.path().filename(),
.file_size = file.file_size(),
.file_size = file.is_directory() ? 0 : file.file_size(),
.is_directory = file.is_directory(),
});
}
@@ -232,7 +242,7 @@ namespace syscalls
files.emplace_back(file_entry{
.file_path = filename,
.file_size = dir_entry.file_size(),
.file_size = dir_entry.is_directory() ? 0 : dir_entry.file_size(),
.is_directory = dir_entry.is_directory(),
});
});
@@ -537,12 +547,68 @@ namespace syscalls
return ret(STATUS_SUCCESS);
}
if (info_class == FileIsRemoteDeviceInformation)
{
if (!f->handle)
{
return ret(STATUS_NOT_SUPPORTED);
}
block.Information = sizeof(FILE_IS_REMOTE_DEVICE_INFORMATION);
if (length < block.Information)
{
return ret(STATUS_BUFFER_OVERFLOW);
}
const emulator_object<FILE_IS_REMOTE_DEVICE_INFORMATION> info{c.emu, file_information};
FILE_IS_REMOTE_DEVICE_INFORMATION i{};
i.IsRemote = FALSE;
info.write(i);
return ret(STATUS_SUCCESS);
}
if (info_class == FileIdInformation)
{
if (!f->handle)
{
return ret(STATUS_NOT_SUPPORTED);
}
block.Information = sizeof(FILE_ID_INFORMATION);
if (length < block.Information)
{
return ret(STATUS_BUFFER_OVERFLOW);
}
struct _stat64 file_stat{};
if (fstat64(f->handle, &file_stat) != 0)
{
return ret(STATUS_INVALID_HANDLE);
}
const emulator_object<FILE_ID_INFORMATION> info{c.emu, file_information};
FILE_ID_INFORMATION i{};
i.VolumeSerialNumber = file_stat.st_dev;
memset(&i.FileId, 0, sizeof(i.FileId));
memcpy(&i.FileId.Identifier[0], &file_stat.st_ino, sizeof(file_stat.st_ino));
info.write(i);
return ret(STATUS_SUCCESS);
}
if (info_class == FileAllInformation)
{
return ret(STATUS_NOT_SUPPORTED);
}
c.win_emu.log.error("Unsupported query file info class: %X\n", info_class);
c.win_emu.log.error("Unsupported query file info class: 0x%X\n", info_class);
c.emu.stop();
return ret(STATUS_NOT_SUPPORTED);

View File

@@ -386,4 +386,9 @@ namespace syscalls
return STATUS_SUCCESS;
}
NTSTATUS handle_NtSetSecurityObject()
{
return STATUS_SUCCESS;
}
}