// // standard printf function with a subset of formating features supported. // // supported // %d, %ld - signed short, signed long // %u, %lu - unsigned short, unsigned long // %c, %s - character, string // %x, %lx - unsigned print in hex, unsigned long print in hex // %wS,%wZ - unicode string // // does not do: // // - field width specification // - floating point. // VOID BlPrint(__in PCHAR cp,...) { PVOID ap = Add2Ptr(&cp,sizeof(PCHAR),PVOID); USHORT b = 0; ULONG Count = 0; ULONG DeviceId = BlConsoleOutDeviceId ? BlConsoleOutDeviceId : 1; while(b = *cp ++) { if(b == '%') { USHORT c = *cp ++; switch(c) { case 'c': ArcWrite(DeviceId,ap,sizeof(UCHAR),&Count); ap = Add2Ptr(ap,sizeof(LONG),PVOID); break; case 'd': puti(*static_cast<PLONG>(ap)); ap = Add2Ptr(ap,sizeof(LONG),PVOID); break; case 'l': { USHORT d = *cp ++; switch(d) { case 'd': puti(*static_cast<PLONG>(ap)); ap = Add2Ptr(ap,sizeof(LONG),PVOID); break; case 'u': putu(*static_cast<PUSHORT>(ap)); ap = Add2Ptr(ap,sizeof(LONG),PVOID); break; case 'x': { ULONG x = *static_cast<PULONG>(ap); ULONG ZeroLength = (x < 0x10) + (x < 0x100) + (x < 0x1000) + (x < 0x10000) + (x < 0x100000) + (x < 0x1000000) + (x < 0x10000000); while(ZeroLength --) ArcWrite(DeviceId,"0",sizeof(UCHAR),&Count); putx(x); ap = Add2Ptr(ap,sizeof(LONG),PVOID); } break; } } break; case 's': { PCHAR String = *static_cast<PCHAR*>(ap); ArcWrite(DeviceId,String,strlen(String),&Count); ap = Add2Ptr(ap,sizeof(PCHAR),PVOID); } break; case 'u': putu(*static_cast<PUSHORT>(ap)); ap = Add2Ptr(ap,sizeof(LONG),PVOID); break; case 'w': { USHORT d = *cp ++; switch(d) { case 'S': case 'W': putwS(*static_cast<PUNICODE_STRING*>(ap)); ap = Add2Ptr(ap,sizeof(PUNICODE_STRING),PVOID); break; } } break; case 'x': { USHORT x = *static_cast<PUSHORT>(ap); ULONG ZeroLength = (x < 0x10) + (x < 0x100) + (x < 0x1000); while(ZeroLength --) ArcWrite(DeviceId,"0",sizeof(UCHAR),&Count); putx(x); ap = Add2Ptr(ap,sizeof(LONG),PVOID); } break; default: ArcWrite(DeviceId,&b,sizeof(UCHAR),&Count); ArcWrite(DeviceId,&c,sizeof(UCHAR),&Count); break; } } else { if(!DbcsLangId || !GrIsDBCSLeadByte(cp[-1])) { ArcWrite(DeviceId,cp - 1,1,&Count); } else { ArcWrite(DeviceId,cp - 1,2,&Count); cp += 1; } } } }
VOID BlPrint( PCHAR cp, ... ) /*++ Routine Description: Standard printf function with a subset of formating features supported. Currently handles %d, %ld - signed short, signed long %u, %lu - unsigned short, unsigned long %c, %s - character, string %x, %lx - unsigned print in hex, unsigned long print in hex Does not do: - field width specification - floating point. Arguments: cp - pointer to the format string, text string. Returns: Nothing --*/ { USHORT b,c,w,len; PUCHAR ap; ULONG l; // // Cast a pointer to the first word on the stack // ap = (PUCHAR)&cp + sizeof(PCHAR); // // Process the arguments using the descriptor string // while(b = *cp++) { if(b == '%') { c = *cp++; switch (c) { case 'd': puti((long)*((int *)ap)); ap += sizeof(int); break; case 's': TextStringOut(*((PCHAR *)ap)); ap += sizeof(char *); break; case 'c': // // Does not handle dbcs chars // pTextCharOut(*((char *)ap)); ap += sizeof(int); break; case 'x': w = *((USHORT *)ap); len = (USHORT)ZLEN_SHORT(w); while(len--) pTextCharOut('0'); putx((ULONG)*((USHORT *)ap)); ap += sizeof(int); break; case 'u': putu((ULONG)*((USHORT *)ap)); ap += sizeof(int); break; case 'w': c = *cp++; switch (c) { case 'S': case 'Z': putwS(*((PUNICODE_STRING *)ap)); ap += sizeof(PUNICODE_STRING); break; } break; case 'l': c = *cp++; switch(c) { case '0': break; case 'u': putu(*((ULONG *)ap)); ap += sizeof(long); break; case 'x': l = *((ULONG *)ap); len = (USHORT)ZLEN_LONG(l); while(len--) pTextCharOut('0'); putx(*((ULONG *)ap)); ap += sizeof(long); break; case 'd': puti(*((ULONG *)ap)); ap += sizeof(long); break; } break; default : pTextCharOut((char)b); pTextCharOut((char)c); } } else { // // Could be a double-byte char. // cp = TextCharOut(cp-1); } } }