ObCreateSymbolicLink/ObDeleteSymbolicLink
This commit is contained in:
parent
9cf324f689
commit
8f92c60a0b
|
@ -169,6 +169,37 @@ SHIM_CALL ObDereferenceObject_shim(PPCContext* ppc_context,
|
|||
SHIM_SET_RETURN_32(0);
|
||||
}
|
||||
|
||||
dword_result_t ObCreateSymbolicLink(pointer_t<X_ANSI_STRING> path,
|
||||
pointer_t<X_ANSI_STRING> target) {
|
||||
auto path_str = path->to_string(kernel_memory()->virtual_membase());
|
||||
auto target_str = target->to_string(kernel_memory()->virtual_membase());
|
||||
path_str = filesystem::CanonicalizePath(path_str);
|
||||
target_str = filesystem::CanonicalizePath(target_str);
|
||||
|
||||
auto pos = path_str.find("\\??\\");
|
||||
if (pos != path_str.npos && pos == 0) {
|
||||
path_str = path_str.substr(4); // Strip the full qualifier
|
||||
}
|
||||
|
||||
if (!kernel_state()->file_system()->RegisterSymbolicLink(path_str,
|
||||
target_str)) {
|
||||
return X_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT(ObCreateSymbolicLink, ExportTag::kImplemented);
|
||||
|
||||
dword_result_t ObDeleteSymbolicLink(pointer_t<X_ANSI_STRING> path) {
|
||||
auto path_str = path->to_string(kernel_memory()->virtual_membase());
|
||||
if (!kernel_state()->file_system()->UnregisterSymbolicLink(path_str)) {
|
||||
return X_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT(ObDeleteSymbolicLink, ExportTag::kImplemented);
|
||||
|
||||
dword_result_t NtDuplicateObject(dword_t handle, lpdword_t new_handle_ptr,
|
||||
dword_t options) {
|
||||
// NOTE: new_handle_ptr can be zero to just close a handle.
|
||||
|
|
|
@ -36,6 +36,8 @@ bool VirtualFileSystem::RegisterSymbolicLink(std::string path,
|
|||
std::string target) {
|
||||
auto global_lock = global_critical_region_.Acquire();
|
||||
symlinks_.insert({path, target});
|
||||
XELOGD("Registered symbolic link: %s => %s", path.c_str(), target.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -45,10 +47,22 @@ bool VirtualFileSystem::UnregisterSymbolicLink(std::string path) {
|
|||
if (it == symlinks_.end()) {
|
||||
return false;
|
||||
}
|
||||
XELOGD("Unregistered symbolic link: %s => %s", it->first.c_str(),
|
||||
it->second.c_str());
|
||||
|
||||
symlinks_.erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VirtualFileSystem::IsSymbolicLink(const std::string& path) {
|
||||
auto global_lock = global_critical_region_.Acquire();
|
||||
auto it = symlinks_.find(path);
|
||||
if (it == symlinks_.end()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Entry* VirtualFileSystem::ResolvePath(std::string path) {
|
||||
auto global_lock = global_critical_region_.Acquire();
|
||||
|
||||
|
@ -58,17 +72,29 @@ Entry* VirtualFileSystem::ResolvePath(std::string path) {
|
|||
// Resolve symlinks.
|
||||
std::string device_path;
|
||||
std::string relative_path;
|
||||
for (const auto& it : symlinks_) {
|
||||
if (xe::find_first_of_case(normalized_path, it.first) == 0) {
|
||||
// Found symlink!
|
||||
device_path = it.second;
|
||||
relative_path = normalized_path.substr(it.first.size());
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (const auto& it : symlinks_) {
|
||||
if (xe::find_first_of_case(normalized_path, it.first) == 0) {
|
||||
// Found symlink!
|
||||
device_path = it.second;
|
||||
if (relative_path.empty()) {
|
||||
relative_path = normalized_path.substr(it.first.size());
|
||||
}
|
||||
|
||||
// Bit of a cheaty move here, but allows double symlinks to be resolved.
|
||||
normalized_path = device_path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Break as soon as we've completely resolved the symlinks to a device.
|
||||
if (!IsSymbolicLink(device_path)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Not to fret, check to see if the path is fully qualified.
|
||||
if (device_path.empty()) {
|
||||
// Symlink wasn't passed in - Check if we've received a raw device name.
|
||||
for (auto& device : devices_) {
|
||||
if (xe::find_first_of_case(normalized_path, device->mount_path()) == 0) {
|
||||
device_path = device->mount_path();
|
||||
|
|
|
@ -32,6 +32,7 @@ class VirtualFileSystem {
|
|||
|
||||
bool RegisterSymbolicLink(std::string path, std::string target);
|
||||
bool UnregisterSymbolicLink(std::string path);
|
||||
bool IsSymbolicLink(const std::string& path);
|
||||
|
||||
Entry* ResolvePath(std::string path);
|
||||
Entry* ResolveBasePath(std::string path);
|
||||
|
|
Loading…
Reference in New Issue