[XAM] Deferred xeXamContentCreate.
This commit is contained in:
parent
e8fda5878c
commit
4498a28568
|
@ -123,7 +123,6 @@ dword_result_t xeXamContentCreate(dword_t user_index, lpstring_t root_name,
|
|||
lpdword_t license_mask_ptr,
|
||||
dword_t cache_size, qword_t content_size,
|
||||
lpvoid_t overlapped_ptr) {
|
||||
X_RESULT result = X_ERROR_INVALID_PARAMETER;
|
||||
XCONTENT_AGGREGATE_DATA content_data;
|
||||
if (content_data_size == sizeof(XCONTENT_DATA)) {
|
||||
content_data = *content_data_ptr.as<XCONTENT_DATA*>();
|
||||
|
@ -131,91 +130,99 @@ dword_result_t xeXamContentCreate(dword_t user_index, lpstring_t root_name,
|
|||
content_data = *content_data_ptr.as<XCONTENT_AGGREGATE_DATA*>();
|
||||
} else {
|
||||
assert_always();
|
||||
return result;
|
||||
return X_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
auto content_manager = kernel_state()->content_manager();
|
||||
bool create = false;
|
||||
bool open = false;
|
||||
switch (flags & 0xF) {
|
||||
case 1: // CREATE_NEW
|
||||
// Fail if exists.
|
||||
if (content_manager->ContentExists(content_data)) {
|
||||
result = X_ERROR_ALREADY_EXISTS;
|
||||
} else {
|
||||
create = true;
|
||||
}
|
||||
break;
|
||||
case 2: // CREATE_ALWAYS
|
||||
// Overwrite existing, if any.
|
||||
if (content_manager->ContentExists(content_data)) {
|
||||
content_manager->DeleteContent(content_data);
|
||||
create = true;
|
||||
} else {
|
||||
create = true;
|
||||
}
|
||||
break;
|
||||
case 3: // OPEN_EXISTING
|
||||
// Open only if exists.
|
||||
if (!content_manager->ContentExists(content_data)) {
|
||||
result = X_ERROR_PATH_NOT_FOUND;
|
||||
} else {
|
||||
open = true;
|
||||
}
|
||||
break;
|
||||
case 4: // OPEN_ALWAYS
|
||||
// Create if needed.
|
||||
if (!content_manager->ContentExists(content_data)) {
|
||||
create = true;
|
||||
} else {
|
||||
open = true;
|
||||
}
|
||||
break;
|
||||
case 5: // TRUNCATE_EXISTING
|
||||
// Fail if doesn't exist, if does exist delete and recreate.
|
||||
if (!content_manager->ContentExists(content_data)) {
|
||||
result = X_ERROR_PATH_NOT_FOUND;
|
||||
} else {
|
||||
content_manager->DeleteContent(content_data);
|
||||
create = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(flags & 0xF);
|
||||
break;
|
||||
|
||||
if (overlapped_ptr && disposition_ptr) {
|
||||
*disposition_ptr = 0;
|
||||
}
|
||||
|
||||
// creation result
|
||||
// 0 = ?
|
||||
// 1 = created
|
||||
// 2 = opened
|
||||
uint32_t disposition = create ? 1 : 2;
|
||||
if (disposition_ptr) {
|
||||
// In case when overlapped_ptr exist we should clear disposition_ptr first
|
||||
// however we're executing it immediately, so it's not required
|
||||
*disposition_ptr = disposition;
|
||||
}
|
||||
|
||||
if (create) {
|
||||
result = content_manager->CreateContent(root_name.value(), content_data);
|
||||
} else if (open) {
|
||||
result = content_manager->OpenContent(root_name.value(), content_data);
|
||||
}
|
||||
|
||||
if (license_mask_ptr && XSUCCEEDED(result)) {
|
||||
*license_mask_ptr = 0; // Stub!
|
||||
}
|
||||
|
||||
if (overlapped_ptr) {
|
||||
X_RESULT extended_error = X_HRESULT_FROM_WIN32(result);
|
||||
if (int32_t(extended_error) < 0) {
|
||||
result = X_ERROR_FUNCTION_FAILED;
|
||||
auto run = [content_manager, root_name, flags, content_data, disposition_ptr,
|
||||
license_mask_ptr](uint32_t& extended_error,
|
||||
uint32_t& length) -> X_RESULT {
|
||||
X_RESULT result = X_ERROR_INVALID_PARAMETER;
|
||||
bool create = false;
|
||||
bool open = false;
|
||||
switch (flags & 0xF) {
|
||||
case 1: // CREATE_NEW
|
||||
// Fail if exists.
|
||||
if (content_manager->ContentExists(content_data)) {
|
||||
result = X_ERROR_ALREADY_EXISTS;
|
||||
} else {
|
||||
create = true;
|
||||
}
|
||||
break;
|
||||
case 2: // CREATE_ALWAYS
|
||||
// Overwrite existing, if any.
|
||||
if (content_manager->ContentExists(content_data)) {
|
||||
content_manager->DeleteContent(content_data);
|
||||
create = true;
|
||||
} else {
|
||||
create = true;
|
||||
}
|
||||
break;
|
||||
case 3: // OPEN_EXISTING
|
||||
// Open only if exists.
|
||||
if (!content_manager->ContentExists(content_data)) {
|
||||
result = X_ERROR_PATH_NOT_FOUND;
|
||||
} else {
|
||||
open = true;
|
||||
}
|
||||
break;
|
||||
case 4: // OPEN_ALWAYS
|
||||
// Create if needed.
|
||||
if (!content_manager->ContentExists(content_data)) {
|
||||
create = true;
|
||||
} else {
|
||||
open = true;
|
||||
}
|
||||
break;
|
||||
case 5: // TRUNCATE_EXISTING
|
||||
// Fail if doesn't exist, if does exist delete and recreate.
|
||||
if (!content_manager->ContentExists(content_data)) {
|
||||
result = X_ERROR_PATH_NOT_FOUND;
|
||||
} else {
|
||||
content_manager->DeleteContent(content_data);
|
||||
create = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(flags & 0xF);
|
||||
break;
|
||||
}
|
||||
kernel_state()->CompleteOverlappedImmediateEx(overlapped_ptr, result,
|
||||
extended_error, disposition);
|
||||
return X_ERROR_IO_PENDING;
|
||||
} else {
|
||||
|
||||
// creation result
|
||||
// 0 = ?
|
||||
// 1 = created
|
||||
// 2 = opened
|
||||
uint32_t disposition = create ? 1 : 2;
|
||||
if (disposition_ptr) {
|
||||
*disposition_ptr = disposition;
|
||||
}
|
||||
|
||||
if (create) {
|
||||
result = content_manager->CreateContent(root_name.value(), content_data);
|
||||
} else if (open) {
|
||||
result = content_manager->OpenContent(root_name.value(), content_data);
|
||||
}
|
||||
|
||||
if (license_mask_ptr && XSUCCEEDED(result)) {
|
||||
*license_mask_ptr = 0; // Stub!
|
||||
}
|
||||
|
||||
extended_error = X_HRESULT_FROM_WIN32(result);
|
||||
length = disposition;
|
||||
return result;
|
||||
};
|
||||
|
||||
if (!overlapped_ptr) {
|
||||
uint32_t extended_error, length;
|
||||
return run(extended_error, length);
|
||||
} else {
|
||||
kernel_state()->CompleteOverlappedDeferredEx(run, overlapped_ptr);
|
||||
return X_ERROR_IO_PENDING;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue