| #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) { |
| int r = 0; |
| int left; |
| int pad; |
| int width; |
| if(!format) return -1; |
| while(*format){ |
| if(*format == '%'){ |
| left = 0; |
| pad = ' '; |
| width = 0; |
| format++; |
| find_specifier: |
| 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)"; |
| width -= strlen(s); |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| while(*s) { |
| putchar(*s++); |
| r++; |
| } |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'd': |
| case 'i':{ |
| char n[12]; |
| int len = sprintf(n, "%d", va_arg(ap, int)); |
| //while(*s) putchar(*s++); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'u':{ |
| char n[12]; |
| int len = sprintf(n, "%u", va_arg(ap, unsigned int)); |
| //while(*n) putchar(*s++); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'o':{ |
| char n[12]; |
| int len = sprintf(n, "%o", va_arg(ap, unsigned int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'x':{ |
| char n[9]; |
| int len = sprintf(n, "%x", va_arg(ap, unsigned int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'X':{ |
| char n[9]; |
| int len = sprintf(n, "%X", va_arg(ap, unsigned int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'e':{ |
| char n[16]; |
| int len = sprintf(n, "%e", va_arg(ap, double)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'f':{ |
| char n[30]; |
| int len = sprintf(n, "%f", va_arg(ap, double)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'g':{ |
| char n[16]; |
| int len = sprintf(n, "%g", va_arg(ap, double)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'h':{ |
| switch(*++format){ |
| case 'd': |
| case 'i':{ |
| char n[8]; |
| int len = sprintf(n, "%hd", va_arg(ap, int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'u':{ |
| char n[6]; |
| int len = sprintf(n, "%hu", va_arg(ap, unsigned int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'o':{ |
| char n[8]; |
| int len = sprintf(n, "%ho", va_arg(ap, unsigned int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'x':{ |
| char n[5]; |
| int len = sprintf(n, "%hx", va_arg(ap, unsigned int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'X':{ |
| char n[5]; |
| int len = sprintf(n, "%hX", va_arg(ap, unsigned int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'h':{ |
| switch(*++format){ |
| case 'd': |
| case 'i':{ |
| char n[5]; |
| int len = sprintf(n, "%hhd", va_arg(ap, int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'u':{ |
| char n[4]; |
| int len = sprintf(n, "%hhu", va_arg(ap, unsigned int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'o':{ |
| char n[4]; |
| int len = sprintf(n, "%hho", va_arg(ap, unsigned int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'x':{ |
| char n[3]; |
| int len = sprintf(n, "%hhx", va_arg(ap, unsigned int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'X':{ |
| char n[3]; |
| int len = sprintf(n, "%hhX", va_arg(ap, unsigned int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| 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]; |
| int len = sprintf(n, "%ld", va_arg(ap, long int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'u':{ |
| char n[22]; |
| int len = sprintf(n, "%lu", va_arg(ap, unsigned long int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'o':{ |
| char n[24]; |
| int len = sprintf(n, "%lo", va_arg(ap, unsigned long int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'x':{ |
| char n[17]; |
| int len = sprintf(n, "%lx", va_arg(ap, unsigned long int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'X':{ |
| char n[17]; |
| int len = sprintf(n, "%lX", va_arg(ap, unsigned long int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'e':{ |
| char n[16]; |
| int len = sprintf(n, "%le", va_arg(ap, double)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'f':{ |
| char n[30]; |
| int len = sprintf(n, "%lf", va_arg(ap, double)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'g':{ |
| char n[16]; |
| int len = sprintf(n, "%lg", va_arg(ap, double)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'l':{ |
| switch(*++format){ |
| case 'd': |
| case 'i':{ |
| char n[22]; |
| int len = sprintf(n, "%lld", va_arg(ap, long long int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'u':{ |
| char n[22]; |
| int len = sprintf(n, "%llu", va_arg(ap, unsigned long long int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'o':{ |
| char n[24]; |
| int len = sprintf(n, "%llo", va_arg(ap, unsigned long long int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'x':{ |
| char n[17]; |
| int len = sprintf(n, "%llx", va_arg(ap, unsigned long long int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'X':{ |
| char n[17]; |
| int len = sprintf(n, "%llX", va_arg(ap, unsigned long long int)); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| 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]; |
| int len = p ? sprintf(n, "0x%.8lx", (unsigned long int)p) : sprintf(n, "(nil)"); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| case 'n':{ |
| *va_arg(ap, int *) = r; |
| format++; |
| break; |
| } |
| case 'z': { |
| size_t z = va_arg(ap, size_t); |
| char n[22]; |
| int len = sprintf(n, "%lu", (unsigned long int)z); |
| width -= len; |
| if(width > 0 && !left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| r += len; |
| print(n); |
| if(width > 0 && left) while(width--) { |
| putchar(pad); |
| r++; |
| } |
| format++; |
| break; |
| } |
| |
| case '-': |
| left = 1; |
| pad = ' '; |
| format++; |
| goto find_specifier; |
| case '0': |
| if(!left) pad = '0'; |
| format++; |
| case '1' ... '9': |
| width = *format - '0'; |
| while(*++format >= '0' && *format <= '9') { |
| width = width * 10 + *format - '0'; |
| } |
| //continue; |
| goto find_specifier; |
| |
| case '%': |
| putchar(*format++); |
| r++; |
| break; |
| |
| default: |
| putchar(*(format-1)); |
| putchar(*(format++)); |
| r += 2; |
| break; |
| } |
| }else{ |
| //default: |
| putchar(*format++); |
| r++; |
| } |
| } |
| 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 tmp1, tmp1 }; |
| return NtDisplayString(&tmp2) < 0 ? EOF : 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) < 0 ? EOF : len; |
| } |