| #include <stdio.h> |
| #include <stdarg.h> |
| #include <windows.h> |
| #include <nt.h> |
| #include <string.h> |
| #include <wchar.h> |
| |
| int putchar(int); |
| |
| static void print(const char *str){ |
| size_t len = strlen(str) + 1; |
| wchar_t buffer[len]; |
| mbstowcs(buffer, str, len); |
| UNICODE_STRING wstrsut = { (len - 1) * sizeof(wchar_t), len * sizeof(wchar_t), buffer }; |
| NtDisplayString(&wstrsut); |
| } |
| |
| int vprintf(const char *format, va_list ap){ |
| if(!format) return -1; |
| int r = 0; |
| while(*format){ |
| if(*format == '%'){ |
| //case '%': |
| format++; |
| switch(*format){ |
| case 'c':{ |
| char c = va_arg(ap, int); |
| putchar(c); |
| format++; |
| r++; |
| break; |
| } |
| case 's':{ |
| char *s = va_arg(ap, char *); |
| if(!s) s = "(null)"; |
| while(*s){ |
| putchar(*s++); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'd': |
| case 'i':{ |
| char n[12]; |
| r += sprintf(n, "%d", va_arg(ap, int)); |
| //while(*s) putchar(*s++); |
| print(n); |
| format++; |
| break; |
| } |
| case 'u':{ |
| char n[12]; |
| r += sprintf(n, "%u", va_arg(ap, unsigned int)); |
| //while(*n) putchar(*s++); |
| print(n); |
| format++; |
| break; |
| } |
| case 'o':{ |
| char n[12]; |
| r += sprintf(n, "%o", va_arg(ap, unsigned int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'x':{ |
| char n[9]; |
| r += sprintf(n, "%x", va_arg(ap, unsigned int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'X':{ |
| char n[9]; |
| r += sprintf(n, "%X", va_arg(ap, unsigned int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'e':{ |
| char n[16]; |
| r += sprintf(n, "%e", va_arg(ap, double)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'f':{ |
| char n[30]; |
| r += sprintf(n, "%f", va_arg(ap, double)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'g':{ |
| char n[16]; |
| r += sprintf(n, "%g", va_arg(ap, double)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'h':{ |
| switch(*++format){ |
| case 'd': |
| case 'i':{ |
| char n[8]; |
| r += sprintf(n, "%hd", va_arg(ap, int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'u':{ |
| char n[6]; |
| r += sprintf(n, "%hu", va_arg(ap, unsigned int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'o':{ |
| char n[8]; |
| r += sprintf(n, "%ho", va_arg(ap, unsigned int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'x':{ |
| char n[5]; |
| r += sprintf(n, "%hx", va_arg(ap, unsigned int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'X':{ |
| char n[5]; |
| r += sprintf(n, "%hX", va_arg(ap, unsigned int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'h':{ |
| switch(*++format){ |
| case 'd': |
| case 'i':{ |
| char n[5]; |
| r += sprintf(n, "%hhd", va_arg(ap, int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'u':{ |
| char n[4]; |
| r += sprintf(n, "%hhu", va_arg(ap, unsigned int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'o':{ |
| char n[4]; |
| r += sprintf(n, "%hho", va_arg(ap, unsigned int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'x':{ |
| char n[3]; |
| r += sprintf(n, "%hhx", va_arg(ap, unsigned int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'X':{ |
| char n[3]; |
| r += sprintf(n, "%hhX", va_arg(ap, unsigned int)); |
| print(n); |
| format++; |
| break; |
| } |
| |
| default: |
| putchar(*(format-3)); |
| r++; |
| break; |
| } // switch |
| break; |
| } // "%hh?" |
| |
| default: |
| putchar(*(format-2)); |
| r++; |
| break; |
| } // switch |
| break; |
| } // "%h?" |
| case 'l':{ |
| switch(*++format){ |
| case 'd': |
| case 'i':{ |
| char n[22]; |
| r += sprintf(n, "%ld", va_arg(ap, long int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'u':{ |
| char n[22]; |
| r += sprintf(n, "%lu", va_arg(ap, unsigned long int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'o':{ |
| char n[24]; |
| r += sprintf(n, "%lo", va_arg(ap, unsigned long int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'x':{ |
| char n[17]; |
| r += sprintf(n, "%lx", va_arg(ap, unsigned long int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'X':{ |
| char n[17]; |
| r += sprintf(n, "%lX", va_arg(ap, unsigned long int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'e':{ |
| char n[16]; |
| r += sprintf(n, "%le", va_arg(ap, double)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'f':{ |
| char n[30]; |
| r += sprintf(n, "%lf", va_arg(ap, double)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'g':{ |
| char n[16]; |
| r += sprintf(n, "%lg", va_arg(ap, double)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'l':{ |
| switch(*++format){ |
| case 'd': |
| case 'i':{ |
| char n[22]; |
| r += sprintf(n, "%lld", va_arg(ap, long long int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'u':{ |
| char n[22]; |
| r += sprintf(n, "%llu", va_arg(ap, unsigned long long int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'o':{ |
| char n[24]; |
| r += sprintf(n, "%llo", va_arg(ap, unsigned long long int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'x':{ |
| char n[17]; |
| r += sprintf(n, "%llx", va_arg(ap, unsigned long long int)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'X':{ |
| char n[17]; |
| r += sprintf(n, "%llX", va_arg(ap, unsigned long long int)); |
| print(n); |
| format++; |
| break; |
| } |
| /* |
| case 'e':{ |
| char n[16]; |
| r += sprintf(n, "%lle", va_arg(ap, long double)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'f':{ |
| char n[30]; |
| r += sprintf(n, "%llf", va_arg(ap, long double)); |
| print(n); |
| format++; |
| break; |
| } |
| case 'g':{ |
| char n[16]; |
| r += sprintf(n, "%llg", va_arg(ap, long double)); |
| print(n); |
| format++; |
| break; |
| } |
| */ |
| default: |
| putchar(*(format-3)); |
| r++; |
| break; |
| } // switch |
| break; |
| } // "%ll?" |
| |
| default: |
| putchar(*(format-2)); |
| r++; |
| break; |
| } |
| break; |
| } // "%l?" |
| case 'p':{ |
| void *p = va_arg(ap, void *); |
| char n[20]; |
| r += p ? sprintf(n, "0x%.8lx", (unsigned long int)p) : sprintf(n, "(nil)"); |
| print(n); |
| format++; |
| break; |
| } |
| case 'n':{ |
| *va_arg(ap, int *) = r; |
| format++; |
| break; |
| } |
| |
| case '%': |
| putchar(*format++); |
| r++; |
| break; |
| default: |
| putchar(*(format-1)); |
| putchar(*(format++)); |
| r += 2; |
| break; |
| } |
| }else{ |
| //default: |
| putchar(*format); |
| r++; |
| format++; |
| } |
| } |
| return r; |
| } |
| |
| int printf(const char *format, ...){ |
| va_list ap; |
| va_start(ap, format); |
| int r = vprintf(format, ap); |
| va_end(ap); |
| return r; |
| } |
| |
| int putchar(int c){ |
| wchar_t tmp1[2]; |
| tmp1[0] = c; |
| tmp1[1] = 0; |
| UNICODE_STRING tmp2 = { sizeof(wchar_t), sizeof(wchar_t) * 2, tmp1 }; |
| return NtDisplayString(&tmp2) ? -1 : c; |
| } |
| |
| int puts(const char *s){ |
| size_t len = strlen(s) + 1; |
| wchar_t buffer[len + 1]; |
| mbstowcs(buffer, s, len); |
| wcscat(buffer, L"\n"); |
| UNICODE_STRING wstrsut = { len * sizeof(wchar_t), (len + 1) * sizeof(wchar_t), buffer }; |
| return NtDisplayString(&wstrsut) ? -1 : len; |
| } |