diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc index d4b607a07..f035da5c8 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc @@ -350,212 +350,212 @@ SHIM_CALL RtlUnicodeStringToAnsiString_shim( } -// TODO: clean me up! -SHIM_CALL _vsnprintf_shim( - xe_ppc_state_t* ppc_state, KernelState* state) { - - uint32_t buffer_ptr = SHIM_GET_ARG_32(0); - uint32_t count = SHIM_GET_ARG_32(1); - uint32_t format_ptr = SHIM_GET_ARG_32(2); - uint32_t arg_ptr = SHIM_GET_ARG_32(3); - - if (format_ptr == 0) { - SHIM_SET_RETURN(-1); - return; - } - - char *buffer = (char *)SHIM_MEM_ADDR(buffer_ptr); // TODO: ensure it never writes past the end of the buffer (count)... - const char *format = (const char *)SHIM_MEM_ADDR(format_ptr); - - int arg_index = 0; - - char *b = buffer; - for (; *format != '\0'; ++format) { - const char *start = format; - - if (*format != '%') { - *b++ = *format; - continue; - } - - ++format; - if (*format == '\0') { - break; - } - - if (*format == '%') { - *b++ = *format; - continue; - } - - const char *end; - end = format; - - // skip flags - while (*end == '-' || - *end == '+' || - *end == ' ' || - *end == '#' || - *end == '0') { - ++end; - } - - if (*end == '\0') { - break; - } - - int arg_extras = 0; - - // skip width - if (*end == '*') { - ++end; - arg_extras++; - } - else { - while (*end >= '0' && *end <= '9') { - ++end; - } - } - - if (*end == '\0') { - break; - } - - // skip precision - if (*end == '.') { - ++end; - - if (*end == '*') { - ++end; - ++arg_extras; - } - else { - while (*end >= '0' && *end <= '9') { - ++end; - } - } - } - - if (*end == '\0') { - break; - } - - // get length - int arg_size = 4; - - if (*end == 'h') { - ++end; - arg_size = 4; - if (*end == 'h') { - ++end; - } - } - else if (*end == 'l') { - ++end; - arg_size = 4; - if (*end == 'l') { - ++end; - arg_size = 8; - } - } - else if (*end == 'j') { - arg_size = 8; - ++end; - } - else if (*end == 'z') { - arg_size = 4; - ++end; - } - else if (*end == 't') { - arg_size = 8; - ++end; - } - else if (*end == 'L') { - arg_size = 8; - ++end; - } - - if (*end == '\0') { - break; - } - - if (*end == 'd' || - *end == 'i' || - *end == 'u' || - *end == 'o' || - *end == 'x' || - *end == 'X' || - *end == 'f' || - *end == 'F' || - *end == 'e' || - *end == 'E' || - *end == 'g' || - *end == 'G' || - *end == 'a' || - *end == 'A' || - *end == 'c') { - char local[512]; - local[0] = '\0'; - strncat(local, start, end + 1 - start); - - XEASSERT(arg_size == 8 || arg_size == 4); - if (arg_size == 8) { - if (arg_extras == 0) { - uint64_t value = SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... - int result = sprintf(b, local, value); - b += result; - arg_index++; - } - else { - XEASSERT(false); - } - } - else if (arg_size == 4) { - if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... - int result = sprintf(b, local, value); - b += result; - arg_index++; - } - else { - XEASSERT(false); - } - } - } - else if (*end == 's' || - *end == 'p' || - *end == 'n') { - char local[512]; - local[0] = '\0'; - strncat(local, start, end + 1 - start); - - XEASSERT(arg_size == 4); - if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... - const char *pointer = (const char *)SHIM_MEM_ADDR(value); - int result = sprintf(b, local, pointer); - b += result; - arg_index++; - } - else { - XEASSERT(false); - } - } - else { - XEASSERT(false); - break; - } - format = end; - } - *b++ = '\0'; - SHIM_SET_RETURN((uint32_t)(b - buffer)); +// TODO: clean me up! +SHIM_CALL _vsnprintf_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + + uint32_t buffer_ptr = SHIM_GET_ARG_32(0); + uint32_t count = SHIM_GET_ARG_32(1); + uint32_t format_ptr = SHIM_GET_ARG_32(2); + uint32_t arg_ptr = SHIM_GET_ARG_32(3); + + if (format_ptr == 0) { + SHIM_SET_RETURN(-1); + return; + } + + char *buffer = (char *)SHIM_MEM_ADDR(buffer_ptr); // TODO: ensure it never writes past the end of the buffer (count)... + const char *format = (const char *)SHIM_MEM_ADDR(format_ptr); + + int arg_index = 0; + + char *b = buffer; + for (; *format != '\0'; ++format) { + const char *start = format; + + if (*format != '%') { + *b++ = *format; + continue; + } + + ++format; + if (*format == '\0') { + break; + } + + if (*format == '%') { + *b++ = *format; + continue; + } + + const char *end; + end = format; + + // skip flags + while (*end == '-' || + *end == '+' || + *end == ' ' || + *end == '#' || + *end == '0') { + ++end; + } + + if (*end == '\0') { + break; + } + + int arg_extras = 0; + + // skip width + if (*end == '*') { + ++end; + arg_extras++; + } + else { + while (*end >= '0' && *end <= '9') { + ++end; + } + } + + if (*end == '\0') { + break; + } + + // skip precision + if (*end == '.') { + ++end; + + if (*end == '*') { + ++end; + ++arg_extras; + } + else { + while (*end >= '0' && *end <= '9') { + ++end; + } + } + } + + if (*end == '\0') { + break; + } + + // get length + int arg_size = 4; + + if (*end == 'h') { + ++end; + arg_size = 4; + if (*end == 'h') { + ++end; + } + } + else if (*end == 'l') { + ++end; + arg_size = 4; + if (*end == 'l') { + ++end; + arg_size = 8; + } + } + else if (*end == 'j') { + arg_size = 8; + ++end; + } + else if (*end == 'z') { + arg_size = 4; + ++end; + } + else if (*end == 't') { + arg_size = 8; + ++end; + } + else if (*end == 'L') { + arg_size = 8; + ++end; + } + + if (*end == '\0') { + break; + } + + if (*end == 'd' || + *end == 'i' || + *end == 'u' || + *end == 'o' || + *end == 'x' || + *end == 'X' || + *end == 'f' || + *end == 'F' || + *end == 'e' || + *end == 'E' || + *end == 'g' || + *end == 'G' || + *end == 'a' || + *end == 'A' || + *end == 'c') { + char local[512]; + local[0] = '\0'; + strncat(local, start, end + 1 - start); + + XEASSERT(arg_size == 8 || arg_size == 4); + if (arg_size == 8) { + if (arg_extras == 0) { + uint64_t value = SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + int result = sprintf(b, local, value); + b += result; + arg_index++; + } + else { + XEASSERT(false); + } + } + else if (arg_size == 4) { + if (arg_extras == 0) { + uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + int result = sprintf(b, local, value); + b += result; + arg_index++; + } + else { + XEASSERT(false); + } + } + } + else if (*end == 's' || + *end == 'p' || + *end == 'n') { + char local[512]; + local[0] = '\0'; + strncat(local, start, end + 1 - start); + + XEASSERT(arg_size == 4); + if (arg_extras == 0) { + uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + const char *pointer = (const char *)SHIM_MEM_ADDR(value); + int result = sprintf(b, local, pointer); + b += result; + arg_index++; + } + else { + XEASSERT(false); + } + } + else { + XEASSERT(false); + break; + } + format = end; + } + *b++ = '\0'; + SHIM_SET_RETURN((uint32_t)(b - buffer)); } uint32_t xeRtlNtStatusToDosError(X_STATUS status) { - if (!status || (status & 0x20000000)) { - // Success. - return status; + if (!status || (status & 0x20000000)) { + // Success. + return status; } else if ((status & 0xF0000000) == 0xD0000000) { // High bit doesn't matter. status &= ~0x10000000;